ZPLII 语言编程基础
链接:https://pan.baidu.com/s/1QTLnnBPgdje7bZ9xMublgQ 提取码:tfu9
0.打印条形码1
搬运出处: https://www.geek-share.com/detail/2623522761.htmlcode-----------------------------^XA^PW1000 ^MD30 ^LH0,0 #CN_DATA1#;|宋体|20|15|^FO150,0 #CN_DATA2#;|宋体|20|15|^FO650,0 ^FO70,0^BY2.0,3.0^BCN,120,Y,N,N,A^FD#ID1#^FS ^FO570,0^BY2.0,3.0^BCN,120,Y,N,N,A^FD#ID2#^FS ^PQ1,0,1,Y ^XZ
code-----------------------------
说明------------------------------^XA和^XZ:分别代表一个指令块的开始和结束, 是固定的东西。
^PW:打印宽度,如果宽度较小,则会出现打印不全的效果。
^MD:设置标签颜色的深度,取值范围为 -30 to 30,上面的指令将颜色调到了最深。
^LH:设置条码纸的边距,本模板未进行设置。
以下以字符串abc^edf~L000001^L000002为例进行说明(abc、edf分别为汉字,L000001、L000002为条形码值)
#CN_DATA1#:为abc的占位符。
#CN_DATA2#:为edf的占位符。
|宋体|20|15|:指字体为宋体,字符高度为20,宽度为15
^FO:设置条码左上角的位置的坐标(70,0)。
^BY:设置条形码显示样式, 这是该模板最重要的一个部分, 2.0是条码的缩放级别(可接受的数值:1-10点 ),这个数值下打出的条码很小, 3.0是条码中粗细柱的比例(可接受的数值:2.0到3.0,增量0.1,对固定比例的条码无效 ), 120是条码高度。
^BCN:是打印code128的指令。
^FD:设置要打印的内容
^FS:表示换行
#ID1#:指L000001
#ID2#:指L000002
^PQ50,10,1,Y:打印总数50张标签每个序列号只打一张。打印每组数量是10,但在每组间不暂停。
^PQ50,10,1,N:打印总数50张标签每个序列号只打一张。打印每数量是10,每组打印后暂停。
这里可以写成^PQ1,0,1,Y,即每次打印一张,不暂停。因为打印总张数可以在程序中进行控制。
说明------------------------------
效果: ![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111110657993-801772046.png)
1. ZPL 二维码打印
二维码打印
^XA
^FO20,20
^BQ,2,10
^FDLA,0123456789ABCD 2D code^FS
^XZ
10.二维码:^BQ
^BQ字段位置,模型,放大倍数(^BQ,2,10 无旋转,模型:增强,放大倍数:10)
^BQ =二维码条码
a =字段位置
默认值:正常。
其他值: 没有旋转是可用的。^的FW命令不影响旋转。
b =模型 默认值:2(增强) 推荐 其他值:1(原创)
c =放大倍数 默认值:1在150 dpi打印机 2在200 dpi打印机 3在300 dpi打印机 其他值:4至10
(c值不同条码大小不同)
11.纠错能力:
L级:约可纠错7%的数据码字
M级:约可纠错15%的数据码字
Q级:约可纠错25%的数据码字
H级:约可纠错30%的数据码字
效果:![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111105606589-1143889808.png)
2.ZPL 设计预览
http://labelary.com/viewer.html
效果: ![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111105715727-755464243.png)
3.打印条形码2
// 搬运: https://www.geek-share.com/detail/2755709722.html
// 准备:
// 1. 斑马打印机 型号GT820。
// 2. 斑马打印机驱动。
// 3. 库文件SMT.ZEBRA.dll 和 SMT.ZEBRA.dll的依赖库文件Fnthex32.dll。
步骤:
// 1。调试打印机,安装支持打印机的ZPL驱动(因为所打印标签的模板使用ZPL指令编写的,所以必须选择ZPL)。
// 打印机属性->测试页,打印成功说明调试成功。
// 2。注册 SMT.ZEBRA.dll 文件, cmd 右键->管理员权限运行-> regram 路径/SMT.ZEBRA.dll 。
// Fnthex32.dll库文件貌似不用注册,详见demo中readme.txt。
// 3。给予DLL文件运行权限。右键DLL文件->属性->安全->编辑->添加->everyone->确定->完全控制->确定。
// 4。项目引用 SMT.ZEBRA.dll ,Fnthex32.dll库文件也不用引用。
Imports System.Drawing.Printing.PrinterSettings
Imports System.Drawing.Printing
Imports System.Text.RegularExpressions
Public Class TestZebraPrinterForm
Private Sub TestZebraPrinterForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim stringCollection As PrinterSettings.StringCollection = PrinterSettings.InstalledPrinters '’得到已安装的打印机名字。
Dim strPrinterName As String = String.Empty
Dim regex As Regex = New Regex("^.*ZPL.*$") '’new 一个正则表达式模板 ,^.*ZPL.*$ 代表包含ZPL的任意字符串。
Dim itemValue As String = ""
For Each strName As String In stringCollection
strPrinterName = strName.ToString()
Printer_ComboBox.Items.Add(strPrinterName) '’添加到组合框。
If regex.IsMatch(strPrinterName) Then '’判断是否满足模板。
itemValue = strPrinterName
End If
Next
Printer_ComboBox.SelectedText = itemValue
End Sub
Private Sub print_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles print_Button.Click
''实例化一个打印类
Dim zebraPrinter As Smt.Zebra.ZebraPrinter = New Smt.Zebra.ZebraPrinter()
For i = 0 To 2
Dim str1 As String = "名称1:" + "内容"
Dim str2 As String = "名称2:" + "内容"
Dim str3 As String = "名称3:" + "内容"
Dim str4 As String = "名称4:" + "内容"
Dim str5 As String = "名称5:" + "内容"
Dim str6 As String = "名称6:" + "内容"
''定义一个标签值
Dim barcode As String = "A" + "00000000" + i.ToString
''按照格式,格式化成新的字符串
'’str1 = String.Concat(" ", "^", " ", "~", str1) ''双排条形码
Dim Str As String = String.Concat(str1, "^", str2, "^", str3, "^", str4, "^", str5, "^", str6, "~", barcode) '单排条形码
''barcodeConfig.TXT:模板配置文件 或barcodeConfig.PRN //一定要大写
''Printer_ComboBox.Text:打印机名称
Dim Path As String = "barcodeConfig.TXT"
zebraPrinter.PrintLabEx(Path, Str, Printer_ComboBox.Text)
Next
End Sub
End Class
下面是打印模板文件barcodeConfig.TXT。
^XA //开始
^PW1000 //条码最大宽
^MD30 //颜色深度
^LH0,0
#CN_DATA1#;|宋体|20|18|^FO100,60 //占位符 //FO横纵坐标
#CN_DATA2#;|宋体|20|18|^FO520,60 //占位符
#CN_DATA3#;|宋体|20|18|^FO100,130 //占位符
#CN_DATA4#;|宋体|20|18|^FO520,130 //占位符
#CN_DATA5#;|宋体|20|18|^FO100,200 //占位符
#CN_DATA6#;|宋体|20|18|^FO520,200 //占位符
//打印条码 //BY缩放大小,条码高度 //(^BCN,120,Y,N,N)打印不旋转的高度为100点的Code128条码。
^FO280,320^BY4.0,3.0^BCN,120,Y,N,N,A^FD#ID1#^FS
^PQ1,0,1,Y
^XZ //结束
效果: ![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111110213795-1896362617.png)
4.C#编程发送ZPL指令驱动斑马打印机打印标签
搬运地址: http://www.shangxi.xyz/autoinsurancedetail.aspx?id=29
代码下载地址: http://www.shangxi.xyz/upload/2018-04-06/30dc9ef2-59da-4b5c-8797-9f775e5b4d19.zip
5.C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
搬运地址: https://blog.csdn.net/ldljlq/article/details/7338772
在批量打印商品标签时一般都要加上条码或图片,而这类应用大多是使用斑马打印机,所以我也遇到了怎么打印的问题。
一种办法是用标签设计软件做好模板,在标签设计软件中打印,这种办法不用写代码,但对我来说觉得不能接受,所以尝试代码解决问题。
网上搜索一番,找不到什么资料,基本都是说发送ZPL、EPL指令到打印机,而且还是COM/LPT口连接打印机。后来研究.net的打印类库,发现是用绘图方式打印至打印机的,也叫GDI打印,于是思路有了点突破,那我可以用报表工具画好标签,运行报表时,把结果输出位图,再发送至打印机。
后来又找到一种更好的办法,利用标签设计软件做好模板,打印至本地文件,把其中的ZPL、EPL指令拷贝出来,替换其中动态变化的内容为变量名,做成一个模板文本,在代码中动态替换变量,再把指令输出至打印机。
折腾了几天,终于把这两种思路都实现了,顺便解决了USB接口打印机的ZPL、EPL指令发送问题。
今天有点困,改天再详细讲解一下这两种思路的具体实现。
==============================================================================================================
如何获取标签设计软件输出至打印的ZPL指令?安装好打印机驱动,修改打印机端口,新建一个打印机端口,类型为本地端口,端口名称设置为C:\printer.log,再用标签设计软件打印一次,此文件中就有ZPL指令了。
==============================================================================================================
2012-06-02:发布代码ZebraPrintHelper.cs。
==============================================================================================================
2013-01-17:发布代码ZebraPrintHelper.cs,修正BUG,新增TCP打印支持Zebra无线打印QL320+系列打印机。已经生产环境实际应用,支持POS小票、吊牌、洗水唛、条码、文本混合标签打印。因涉及公司源码,只能截图VS解决方案给大家看。
==============================================================================================================
ZebraPrintHelper类代码:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Ports;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
namespace Umisky.BarcodePrint.Core {
///
/// 斑马打印助手,支持LPT/COM/USB/TCP四种模式,适用于标签、票据、条码打印。
///
public static class ZebraPrintHelper {
#region 定义私有字段
///
/// 线程锁,防止多线程调用。
///
private static object SyncRoot = new object();
///
/// ZPL压缩字典
///
private static List compressDictionary = new List();
#endregion
#region 定义属性
public static float TcpLabelMaxHeightCM { get; set; }
public static int TcpPrinterDPI { get; set; }
public static string TcpIpAddress { get; set; }
public static int TcpPort { get; set; }
public static int Copies { get; set; }
public static int Port { get; set; }
public static string PrinterName { get; set; }
public static bool IsWriteLog { get; set; }
public static DeviceType PrinterType { get; set; }
public static ProgrammingLanguage PrinterProgrammingLanguage { get; set; }
///
/// 日志保存目录,WEB应用注意不能放在BIN目录下。
///
public static string LogsDirectory { get; set; }
public static byte[] GraphBuffer { get; set; }
private static int GraphWidth { get; set; }
private static int GraphHeight { get; set; }
private static int RowSize {
get {
return (((GraphWidth) + 31) >> 5) 0) {
return GraphWidth / 8 + 1;
}
else {
return GraphWidth / 8;
}
}
}
#endregion
#region 静态构造方法
static ZebraPrintHelper() {
initCompressCode();
Port = 1;
GraphBuffer = new byte[0];
IsWriteLog = false;
LogsDirectory = "logs";
PrinterProgrammingLanguage = ProgrammingLanguage.ZPL;
}
private static void initCompressCode() {
//G H I J K L M N O P Q R S T U V W X Y 对应1,2,3,4……18,19。
//g h i j k l m n o p q r s t u v w x y z 对应20,40,60,80……340,360,380,400。
for (int i = 0; i < 19; i++) {
compressDictionary.Add(new KeyValue() { Key = Convert.ToChar(71 + i), Value = i + 1 });
}
for (int i = 0; i < 20; i++) {
compressDictionary.Add(new KeyValue() { Key = Convert.ToChar(103 + i), Value = (i + 1) * 20 });
}
}
#endregion
#region 日志记录方法
private static void WriteLog(string text, LogType logType) {
string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
if (!Directory.Exists(LogsDirectory)) {
Directory.CreateDirectory(LogsDirectory);
}
if (logType == LogType.Error) {
File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.UTF8);
}
if (logType == LogType.Print) {
File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.UTF8);
}
}
private static void WriteLog(byte[] bytes, LogType logType) {
string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
if (!Directory.Exists(LogsDirectory)) {
Directory.CreateDirectory(LogsDirectory);
}
if (logType == LogType.Error) {
File.AppendAllText(path, string.Format("{0}{1}", Encoding.UTF8.GetString(bytes), endTag), Encoding.UTF8);
}
if (logType == LogType.Print) {
File.AppendAllText(path, string.Format("{0}{1}", Encoding.UTF8.GetString(bytes), endTag), Encoding.UTF8);
}
}
#endregion
#region 封装方法,方便调用。
public static bool PrintWithCOM(string cmd, int port, bool isWriteLog) {
PrinterType = DeviceType.COM;
Port = port;
IsWriteLog = isWriteLog;
return PrintCommand(cmd);
}
public static bool PrintWithCOM(byte[] bytes, int port, bool isWriteLog) {
PrinterType = DeviceType.COM;
Port = port;
IsWriteLog = isWriteLog;
return PrintGraphics(bytes);
}
public static bool PrintWithLPT(string cmd, int port, bool isWriteLog) {
PrinterType = DeviceType.LPT;
Port = port;
IsWriteLog = isWriteLog;
return PrintCommand(cmd);
}
public static bool PrintWithLPT(byte[] bytes, int port, bool isWriteLog) {
PrinterType = DeviceType.LPT;
Port = port;
IsWriteLog = isWriteLog;
return PrintGraphics(bytes);
}
public static bool PrintWithTCP(string cmd, bool isWriteLog) {
PrinterType = DeviceType.TCP;
IsWriteLog = isWriteLog;
return PrintCommand(cmd);
}
public static bool PrintWithTCP(byte[] bytes, bool isWriteLog) {
PrinterType = DeviceType.TCP;
IsWriteLog = isWriteLog;
return PrintGraphics(bytes);
}
public static bool PrintWithDRV(string cmd, string printerName, bool isWriteLog) {
PrinterType = DeviceType.DRV;
PrinterName = printerName;
IsWriteLog = isWriteLog;
return PrintCommand(cmd);
}
public static bool PrintWithDRV(byte[] bytes, string printerName, bool isWriteLog) {
PrinterType = DeviceType.DRV;
PrinterName = printerName;
IsWriteLog = isWriteLog;
return PrintGraphics(bytes);
}
#endregion
#region 打印ZPL、EPL、CPCL、TCP指令
public static bool PrintCommand(string cmd) {
lock (SyncRoot) {
bool result = false;
try {
switch (PrinterType) {
case DeviceType.COM:
result = comPrint(Encoding.Default.GetBytes(cmd));
break;
case DeviceType.LPT:
result = lptPrint(Encoding.Default.GetBytes(cmd));
break;
case DeviceType.DRV:
result = drvPrint(Encoding.Default.GetBytes(cmd));
break;
case DeviceType.TCP:
result = tcpPrint(Encoding.Default.GetBytes(cmd));
break;
}
if (!string.IsNullOrEmpty(cmd) && IsWriteLog) {
WriteLog(cmd, LogType.Print);
}
}
catch (Exception ex) {
//记录日志
if (IsWriteLog) {
WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
}
throw new Exception(ex.Message, ex);
}
finally {
GraphBuffer = new byte[0];
}
return result;
}
}
#endregion
#region 打印图像
public static bool PrintGraphics(byte[] graph) {
lock (SyncRoot) {
bool result = false;
try {
GraphBuffer = graph;
byte[] cmdBytes = new byte[0];
switch (PrinterProgrammingLanguage) {
case ProgrammingLanguage.ZPL:
cmdBytes = getZPLBytes();
break;
case ProgrammingLanguage.EPL:
cmdBytes = getEPLBytes();
break;
case ProgrammingLanguage.CPCL:
cmdBytes = getCPCLBytes();
break;
}
switch (PrinterType) {
case DeviceType.COM:
result = comPrint(cmdBytes);
break;
case DeviceType.LPT:
result = lptPrint(cmdBytes);
break;
case DeviceType.DRV:
result = drvPrint(cmdBytes);
break;
case DeviceType.TCP:
result = tcpPrint(cmdBytes);
break;
}
if (cmdBytes.Length > 0 && IsWriteLog) {
WriteLog(cmdBytes, LogType.Print);
}
}
catch (Exception ex) {
//记录日志
if (IsWriteLog) {
WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
}
throw new Exception(ex.Message, ex);
}
finally {
GraphBuffer = new byte[0];
}
return result;
}
}
#endregion
#region 打印指令
private static bool drvPrint(byte[] cmdBytes) {
bool result = false;
try {
if (!string.IsNullOrEmpty(PrinterName)) {
result = WinDrvPort.SendBytesToPrinter(PrinterName, cmdBytes);
}
}
catch (Exception ex) {
throw new Exception(ex.Message, ex);
}
return result;
}
private static bool comPrint(byte[] cmdBytes) {
bool result = false;
SerialPort com = new SerialPort(string.Format("{0}{1}", PrinterType, Port), 9600, Parity.None, 8, StopBits.One);
try {
com.Open();
com.Write(cmdBytes, 0, cmdBytes.Length);
result = true;
}
catch (Exception ex) {
throw new Exception(ex.Message, ex);
}
finally {
if (com.IsOpen) {
com.Close();
}
}
return result;
}
private static bool lptPrint(byte[] cmdBytes) {
return LptPort.Write(string.Format("{0}{1}", PrinterType, Port), cmdBytes);
}
private static bool tcpPrint(byte[] cmdBytes) {
bool result = false;
TcpClient tcp = null;
try {
tcp = TimeoutSocket.Connect(string.Empty, TcpIpAddress, TcpPort, 1000);
tcp.SendTimeout = 1000;
tcp.ReceiveTimeout = 1000;
if (tcp.Connected) {
tcp.Client.Send(cmdBytes);
result = true;
}
}
catch (Exception ex) {
throw new Exception("打印失败,请检查打印机或网络设置。", ex);
}
finally {
if (tcp != null) {
if (tcp.Client != null) {
tcp.Client.Close();
tcp.Client = null;
}
tcp.Close();
tcp = null;
}
}
return result;
}
#endregion
#region 生成ZPL图像打印指令
private static byte[] getZPLBytes() {
byte[] bmpData = getBitmapData();
int bmpDataLength = bmpData.Length;
for (int i = 0; i < bmpDataLength; i++) {
bmpData[i] ^= 0xFF;
}
string textBitmap = string.Empty, copiesString = string.Empty;
string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
textBitmap = CompressLZ77(textHex);
for (int i = 0; i < Copies; i++) {
copiesString += "^XA^FO0,0^XGR:IMAGE.GRF,1,1^FS^XZ";
}
string text = string.Format("~DGR:IMAGE.GRF,{0},{1},{2}{3}^IDR:IMAGE.GRF",
GraphHeight * RowRealBytesCount,
RowRealBytesCount,
textBitmap,
copiesString);
return Encoding.UTF8.GetBytes(text);
}
#endregion
#region 生成EPL图像打印指令
private static byte[] getEPLBytes() {
byte[] buffer = getBitmapData();
string text = string.Format("N\r\nGW{0},{1},{2},{3},{4}\r\nP{5},1\r\n",
0,
0,
RowRealBytesCount,
GraphHeight,
Encoding.GetEncoding("iso-8859-1").GetString(buffer),
Copies);
return Encoding.GetEncoding("iso-8859-1").GetBytes(text);
}
#endregion
#region 生成CPCL图像打印指令
public static byte[] getCPCLBytes() {
//GRAPHICS Commands
//Bit-mapped graphics can be printed by using graphics commands. ASCII hex (hexadecimal) is
//used for expanded graphics data (see example). Data size can be reduced to one-half by utilizing the
//COMPRESSED-GRAPHICS commands with the equivalent binary character(s) of the hex data. When
//using CG, a single 8 bit character is sent for every 8 bits of graphics data. When using EG two characters
//(16 bits) are used to transmit 8 bits of graphics data, making EG only half as efficient. Since this data is
//character data, however, it can be easier to handle and transmit than binary data.
//Format:
//{command} {width} {height} {x} {y} {data}
//where:
//{command}: Choose from the following:
//EXPANDED-GRAPHICS (or EG): Prints expanded graphics horizontally.
//VEXPANDED-GRAPHICS (or VEG): Prints expanded graphics vertically.
//COMPRESSED-GRAPHICS (or CG): Prints compressed graphics horizontally.
//VCOMPRESSED-GRAPHICS (or VCG): Prints compressed graphics vertically.
//{width}: Byte-width of image.
//{height} Dot-height of image.
//{x}: Horizontal starting position.
//{y}: Vertical starting position.
//{data}: Graphics data.
//Graphics command example
//Input:
//! 0 200 200 210 1
//EG 2 16 90 45 F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F
//F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F
//FORM
//PRINT
byte[] bmpData = getBitmapData();
int bmpDataLength = bmpData.Length;
for (int i = 0; i < bmpDataLength; i++) {
bmpData[i] ^= 0xFF;
}
string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
string text = string.Format("! {0} {1} {2} {3} {4}\r\nEG {5} {6} {7} {8} {9}\r\nFORM\r\nPRINT\r\n",
0, //水平偏移量
TcpPrinterDPI, //横向DPI
TcpPrinterDPI, //纵向DPI
(int)(TcpLabelMaxHeightCM / 2.54f * TcpPrinterDPI), //标签最大像素高度=DPI*标签纸高度(英寸)
Copies, //份数
RowRealBytesCount, //图像的字节宽度
GraphHeight, //图像的像素高度
0, //横向的开始位置
0, //纵向的开始位置
textHex
);
return Encoding.UTF8.GetBytes(text);
}
#endregion
#region 获取单色位图数据
///
///
///
///
///
public static Bitmap ConvertToGrayscale(Bitmap pimage) {
Bitmap source = null;
// If original bitmap is not already in 32 BPP, ARGB format, then convert
if (pimage.PixelFormat != PixelFormat.Format32bppArgb) {
source = new Bitmap(pimage.Width, pimage.Height, PixelFormat.Format32bppArgb);
source.SetResolution(pimage.HorizontalResolution, pimage.VerticalResolution);
using (Graphics g = Graphics.FromImage(source)) {
g.DrawImageUnscaled(pimage, 0, 0);
}
}
else {
source = pimage;
}
// Lock source bitmap in memory
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Copy image data to binary array
int imageSize = sourceData.Stride * sourceData.Height;
byte[] sourceBuffer = new byte[imageSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);
// Unlock source bitmap
source.UnlockBits(sourceData);
// Create destination bitmap
Bitmap destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed);
// Lock destination bitmap in memory
BitmapData destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
// Create destination buffer
imageSize = destinationData.Stride * destinationData.Height;
byte[] destinationBuffer = new byte[imageSize];
int sourceIndex = 0;
int destinationIndex = 0;
int pixelTotal = 0;
byte destinationValue = 0;
int pixelValue = 128;
int height = source.Height;
int width = source.Width;
int threshold = 500;
// Iterate lines
for (int y = 0; y < height; y++) {
sourceIndex = y * sourceData.Stride;
destinationIndex = y * destinationData.Stride;
destinationValue = 0;
pixelValue = 128;
// Iterate pixels
for (int x = 0; x < width; x++) {
// Compute pixel brightness (i.e. total of Red, Green, and Blue values)
pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3];
if (pixelTotal > threshold) {
destinationValue += (byte)pixelValue;
}
if (pixelValue == 1) {
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = 0;
pixelValue = 128;
}
else {
pixelValue >>= 1;
}
sourceIndex += 4;
}
if (pixelValue != 128) {
destinationBuffer[destinationIndex] = destinationValue;
}
}
// Copy binary image data to destination bitmap
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);
// Unlock destination bitmap
destination.UnlockBits(destinationData);
// Dispose of source if not originally supplied bitmap
if (source != pimage) {
source.Dispose();
}
// Return
return destination;
}
///
/// 获取单色位图数据(1bpp),不含文件头、信息头、调色板三类数据。
///
///
private static byte[] getBitmapData() {
MemoryStream srcStream = new MemoryStream();
MemoryStream dstStream = new MemoryStream();
Bitmap srcBmp = null;
Bitmap dstBmp = null;
byte[] srcBuffer = null;
byte[] dstBuffer = null;
byte[] result = null;
try {
srcStream = new MemoryStream(GraphBuffer);
srcBmp = Bitmap.FromStream(srcStream) as Bitmap;
srcBuffer = srcStream.ToArray();
GraphWidth = srcBmp.Width;
GraphHeight = srcBmp.Height;
//dstBmp = srcBmp.Clone(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), PixelFormat.Format1bppIndexed);
dstBmp = ConvertToGrayscale(srcBmp);
dstBmp.Save(dstStream, ImageFormat.Bmp);
dstBuffer = dstStream.ToArray();
int bfOffBits = BitConverter.ToInt32(dstBuffer, 10);
result = new byte[GraphHeight * RowRealBytesCount];
//读取时需要反向读取每行字节实现上下翻转的效果,打印机打印顺序需要这样读取。
for (int i = 0; i < GraphHeight; i++) {
Array.Copy(dstBuffer, bfOffBits + (GraphHeight - 1 - i) * RowSize, result, i * RowRealBytesCount, RowRealBytesCount);
}
}
catch (Exception ex) {
throw new Exception(ex.Message, ex);
}
finally {
if (srcStream != null) {
srcStream.Dispose();
srcStream = null;
}
if (dstStream != null) {
dstStream.Dispose();
dstStream = null;
}
if (srcBmp != null) {
srcBmp.Dispose();
srcBmp = null;
}
if (dstBmp != null) {
dstBmp.Dispose();
dstBmp = null;
}
}
return result;
}
#endregion
#region LZ77图像字节流压缩方法
public static string CompressLZ77(string text) {
//将转成16进制的文本进行压缩
string result = string.Empty;
char[] arrChar = text.ToCharArray();
int count = 1;
for (int i = 1; i < text.Length; i++) {
if (arrChar[i - 1] == arrChar[i]) {
count++;
}
else {
result += convertNumber(count) + arrChar[i - 1];
count = 1;
}
if (i == text.Length - 1) {
result += convertNumber(count) + arrChar[i];
}
}
return result;
}
public static string DecompressLZ77(string text) {
string result = string.Empty;
char[] arrChar = text.ToCharArray();
int count = 0;
for (int i = 0; i < arrChar.Length; i++) {
if (isHexChar(arrChar[i])) {
//十六进制值
result += new string(arrChar[i], count == 0 ? 1 : count);
count = 0;
}
else {
//压缩码
int value = GetCompressValue(arrChar[i]);
count += value;
}
}
return result;
}
private static int GetCompressValue(char c) {
int result = 0;
for (int i = 0; i < compressDictionary.Count; i++) {
if (c == compressDictionary[i].Key) {
result = compressDictionary[i].Value;
}
}
return result;
}
private static bool isHexChar(char c) {
return c > 47 && c < 58 || c > 64 && c < 71 || c > 96 && c < 103;
}
private static string convertNumber(int count) {
//将连续的数字转换成LZ77压缩代码,如000可用I0表示。
string result = string.Empty;
if (count > 1) {
while (count > 0) {
for (int i = compressDictionary.Count - 1; i >= 0; i--) {
if (count >= compressDictionary[i].Value) {
result += compressDictionary[i].Key;
count -= compressDictionary[i].Value;
break;
}
}
}
}
return result;
}
#endregion
}
}
调用例子代码:
private void BackgroundWorkerPrint_DoWork(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = sender as BackgroundWorker;
int i = 0, nextRemainder = 0, count = this._listBarcodeData.Count;
bool flag = true;
float pageWidth, pageHeight;
int dpiX, dpiY, perPaperFactor;
string reportPath = string.Format(@"{0}/Reports/{1}", Application.StartupPath, this._modelType);
PrintLog printLog = new PrintLog() { Operater = LoginName };
PrinterSettings printerSettings = new PrinterSettings() { PrinterName = PrintParam, Copies = 1 };
using (StreamReader tr = new StreamReader(this.ModelFilePath)) {
XElement xe = XDocument.Load(tr).Root.Elements()
.Elements(XName.Get("ModelType")).First(x => x.Value == this._modelType).Parent;
pageWidth = float.Parse(xe.Elements(XName.Get("PageWidth")).First().Value);
pageHeight = float.Parse(xe.Elements(XName.Get("PageHeight")).First().Value);
dpiX = int.Parse(xe.Elements(XName.Get("DotPerInchX")).First().Value);
dpiY = int.Parse(xe.Elements(XName.Get("DotPerInchY")).First().Value);
perPaperFactor = int.Parse(xe.Elements(XName.Get("PerPaperFactor")).First().Value);
this._no = int.Parse(xe.Elements(XName.Get("NO")).First().Value);
}
using (LocalReportHelper printHelper = new LocalReportHelper(reportPath)) {
printHelper.PrintTypeNO = this._no;
printHelper.PrintLogInformation = printLog;
printHelper.ExportImageDeviceInfo.DpiX = dpiX;
printHelper.ExportImageDeviceInfo.DpiY = dpiY;
printHelper.ExportImageDeviceInfo.PageWidth = pageWidth;
printHelper.ExportImageDeviceInfo.PageHeight = pageHeight;
foreach (BarcodeData bdCurrent in this._listBarcodeData) {
if (worker.CancellationPending == true) {
e.Cancel = true;
break;
}
else {
try {
DataSet dsCurrent = this.GetDataForPrinterByBarcode(bdCurrent.Barcode, bdCurrent.IncreaseType);
DataSet dsNext = null, dsPrevious = dsCurrent.Copy();
int amount = this._printType == 0 ? 1 : bdCurrent.Amount - nextRemainder;
int copies = amount / perPaperFactor;
int remainder = nextRemainder = amount % perPaperFactor;
Action actPrint = (ds, duplicates, barcodes, amountForLog) => {
printHelper.PrintLogInformation.Barcode = barcodes;
printHelper.PrintLogInformation.Amount = amountForLog;
if (this.PrintType == 0 && DeviceType == DeviceType.DRV) {
printerSettings.Copies = (short)duplicates;
printHelper.WindowsDriverPrint(printerSettings, dpiX, ds);
}
else {
printHelper.OriginalPrint(DeviceType, ds, duplicates, PrintParam);
}
};
if (copies > 0) {
int amountForCopy = copies;
if (perPaperFactor > 1) {
DataSet dsCurrentCopy = dsCurrent.CopyForBarcode();
dsCurrent.Merge(dsCurrentCopy);
amountForCopy = copies * perPaperFactor;
}
actPrint.Invoke(dsCurrent, copies, bdCurrent.Barcode, amountForCopy);
}
if (remainder > 0) {
int nextIndex = i + 1;
string barcodes = bdCurrent.Barcode;
if (nextIndex = -1 || this.PrintTypeNO == -3) {
this.AddBarcodesAssembly();
if (this.PrintTypeNO >= 0) {
this.AddWashIcones();
}
}
if (this.PrintTypeNO >= 0) {
this.LocalReportInstance.DataSources.Clear();
foreach (DataTable dt in this._ds.Tables) {
this.LocalReportInstance.DataSources.Add(new ReportDataSource(dt.TableName, dt));
}
}
this.LocalReportInstance.Refresh();
if (this._stream != null) {
this._stream.Close();
this._stream = null;
}
Warning[] warnings;
this.LocalReportInstance.Render(
"Image",
this.ExportImageDeviceInfo.ToString(),
PageCountMode.Actual,
CreateStreamCallBack,
out warnings);
this._stream.Position = 0;
}
private void SaveLog() {
using (Bitmap image = (Bitmap)Image.FromStream(this._stream)) {
image.SetResolution(96, 96);
using (MemoryStream ms = new MemoryStream()) {
image.Save(ms, ImageFormat.Jpeg);
this.PrintLogInformation.BarcodeImage = ms.ToArray();
}
}
LogHelper.AddLog(this.PrintLogInformation);
if (this._stream != null) {
this._stream.Close();
this._stream = null;
}
}
#endregion
#region Windows driver print
private void PrintPage(object sender, PrintPageEventArgs ev) {
Bitmap bmp = (Bitmap)Image.FromStream(this._stream);
bmp.SetResolution(this._bmpDPI, this._bmpDPI);
ev.Graphics.DrawImage(bmp, 0, 0);
ev.HasMorePages = false;
}
///
/// Print by windows driver
///
/// .net framework PrinterSettings class, including some printer information
/// the bitmap image resoluation, dots per inch
public void WindowsDriverPrint(PrinterSettings printerSettings, int bmpDPI, DataSet ds) {
this._ds = ds;
this.Export();
if (this._stream == null) {
return;
}
this._bmpDPI = bmpDPI;
PrintDocument printDoc = new PrintDocument();
printDoc.DocumentName = "条码打印";
printDoc.PrinterSettings = printerSettings;
printDoc.PrintController = new StandardPrintController();
if (!printDoc.PrinterSettings.IsValid) {
if (this._stream != null) {
this._stream.Close();
this._stream = null;
}
MessageBox.Show("Printer found errors, Please contact your administrators!", "Print Error");
return;
}
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
printDoc.Print();
this.SaveLog();
}
#endregion
#region Original print
///
/// Send the file to the printer or use the printer command
///
/// The port(LPT,COM,DRV) which the device connecting
/// Total number for print
/// The report datasource
/// Print parameters
/// The built-in printer programming language, you can choose EPL or ZPL
public void OriginalPrint(DeviceType deviceType,
DataSet ds,
int copies = 1,
string printParam = null,
ProgrammingLanguage printLanguage = ProgrammingLanguage.ZPL) {
this._ds = ds;
this.Export();
if (this._stream == null) {
return;
}
int port = 1;
int.TryParse(printParam, out port);
int length = (int)this._stream.Length;
byte[] bytes = new byte[length];
this._stream.Read(bytes, 0, length);
ZebraPrintHelper.Copies = copies;
ZebraPrintHelper.PrinterType = deviceType;
ZebraPrintHelper.PrinterName = printParam;
ZebraPrintHelper.Port = port;
ZebraPrintHelper.PrinterProgrammingLanguage = printLanguage;
ZebraPrintHelper.PrintGraphics(bytes);
this.SaveLog();
}
#endregion
}
}
View Code
效果: ![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111111729386-1252746200.png)
![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111111734937-313577558.png)
![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111111741957-237695081.png)
![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111111748352-767034912.png)
![](https://img2020.cnblogs.com/blog/1867875/202011/1867875-20201111111754292-507820423.png)
6.C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)
// 搬运来源: https://www.cnblogs.com/chengeng/p/6136185.html
// Printer IP Address and communication port
string ipAddress = "10.3.14.42";
int port = 9100;
// ZPL Command(s)
string ZPLString =
"^XA" +
"^FO50,50" +
"^A0N50,50" +
"^FDHello, World!^FS" +
"^XZ";
try
{
// Open connection
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
client.Connect(ipAddress, port);
// Write ZPL String to connection
System.IO.StreamWriter writer =
new System.IO.StreamWriter(client.GetStream());
writer.Write(ZPLString);
writer.Flush();
// Close Connection
writer.Close();
client.Close();
}
catch (Exception ex)
{
// Catch Exception
}
7.C#通过命令发送的方式,实现斑马打印机zpl命令打印
搬运来源: https://blog.csdn.net/yfy9528/article/details/100989046?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
效果: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190918164923209.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lmeTk1Mjg=,size_16,color_FFFFFF,t_70)
![开始拿代码来运行的时候会报错。解决办法如下](https://img-blog.csdnimg.cn/20190918165208889.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lmeTk1Mjg=,size_16,color_FFFFFF,t_70)
![如果出错,把86修改为64就解决了](https://img-blog.csdnimg.cn/20190918165346609.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lmeTk1Mjg=,size_16,color_FFFFFF,t_70)
![如果出错,把86修改为64就解决了](https://img-blog.csdnimg.cn/20190918165346609.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lmeTk1Mjg=,size_16,color_FFFFFF,t_70)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
namespace Printer1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn_print_Click(object sender, EventArgs e)
{
PrintZPL(txt_zpl.Text);
}
public bool PrintZPL(string zpl)
{
return RawPrinterHelper.SendStringToPrinter("ZDesigner ZT210-300dpi ZPL", zpl);
}
public class RawPrinterHelper
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DOCINFOW
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterW", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool OpenPrinter(string src, ref IntPtr hPrinter, long pd);
[DllImport("winspool.Drv", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterW", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool StartDocPrinter(IntPtr hPrinter, int level, ref RawPrinterHelper.DOCINFOW pDI);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, ref int dwWritten);
// SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
bool bSuccess = false; // Assume failure unless you specifically succeed.
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = System.IntPtr.Zero;// new IntPtr(0);
DOCINFOW di = new DOCINFOW();
di.pDocName = DateTime.Now.ToString("yyyymmddhhMMss") + DateTime.Now.Millisecond.ToString(); //"My C#.NET RAW Document";
di.pDataType = "RAW";
di.pOutputFile = null;
// Open the printer..nNormalize()
if (OpenPrinter(szPrinterName, ref hPrinter, 0))
{
// Start a document.
if (StartDocPrinter(hPrinter, 1, ref di))
{
// Start a page.
if (StartPagePrinter(hPrinter))
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
bool bSuccess = false;
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
try
{
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs, System.Text.Encoding.Default);
// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return bSuccess;
}
finally
{
if (fs != null)
{
fs.Close();
}
}
}
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
// How many characters are in the string?
dwCount = szString.Length;
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
// Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
}
}
8.C# 简单的ZEBRA标签打印程序
搬运出处: https://blog.csdn.net/jianmtao/article/details/7324351?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
Zebra打印机有专用的的语言ZPL,简单的使用C#编程打印方法:
1. 写ZPL脚本,定义好相关打印格式,数据名,等,此保存为txt格式即可
脚本可以用BARONE5.0程序生成,
2. 通过C#程序,操作脚本txt文件,将需要打印的数据替换进脚本
C#如何操作txt,简单的不要再说了
3. 将此脚本通过DOS copy的方法,直接copy到ZEBRA的LPT口即可
//将脚本送到打印口
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Arguments = "/c copy script-go.txt LPT1 ";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.Start();
while (true)
{
if (cmd.HasExited)
{
break;
}
System.Threading.Thread.Sleep(400);
}
完整实例:
打印标签,替换4点为1点,通过code取得名称,etc
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.IO;
using System.Diagnostics;
namespace LabelPrint
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
//using skin
Sunisoft.IrisSkin.SkinEngine MySkin;
MySkin = new Sunisoft.IrisSkin.SkinEngine(this);
MySkin.SkinFile = "MacOS.ssk";
}
//产生脚本的函数,将script内代码读取,参数替换,并生成新的script-go.txt
private string ScriptStr, F_ScriptStr;
private void ScriptGen()
{
StreamReader SR = new StreamReader("script.txt");
ScriptStr = SR.ReadToEnd();
SR.Close();
F_ScriptStr = ScriptStr.Replace("$sn$", F_SN);
F_ScriptStr = F_ScriptStr.Replace("$itemcode$", F_IC);
F_ScriptStr = F_ScriptStr.Replace("$itemname$", F_IN);
//得到修改后的字符串F_ScriptStr
//生成新的txt文件
File.Delete("script-go.txt");
StreamWriter SW = new StreamWriter("script-go.txt", true);
SW.Write(F_ScriptStr);
SW.Close();
}
//输入框内的SN,输入框内的ItemCode,最终SN,最终ItemCode,最终ItemName
private string SN, IC, F_SN, F_IC, F_IN;
private void buttonPrint_Click_1(object sender, EventArgs e)
{
SN = textBoxSN.Text;
IC = textBoxCode.Text;
int SN_Len, IC_Len;
SN_Len = SN.Length;
IC_Len = IC.Length;
//判断输入框内是否输入数据,数据位数是否正确
if (SN_Len != 11)
{
MessageBox.Show("! Wrong : Please check the SN");
textBoxSN.Focus();
textBoxSN.SelectAll();
return;
}
if (IC_Len < 11)
{
MessageBox.Show("! Wrong : Please check the itemcode");
textBoxCode.Focus();
textBoxCode.SelectAll();
return;
}
//取出Itemcode的“4点”
string F_IC1, F_IC2;
F_SN = SN;
F_IC1 = IC.Substring(0, 8);//已经包含"."
switch (IC_Len)
{
case 11:
F_IC2 = IC.Substring(8, 3);
F_IC = F_IC1 + F_IC2;
break;
case 12:
F_IC2 = IC.Substring(8, 4);
F_IC = F_IC1 + F_IC2;
break;
case 14:
F_IC2 = IC.Substring(11, 3);
F_IC = F_IC1 + F_IC2;
break;
case 15:
F_IC2 = IC.Substring(11, 4);
F_IC = F_IC1 + F_IC2;
break;
default:
MessageBox.Show("! Wrong : Please check the itemcode");
textBoxCode.Focus();
textBoxCode.SelectAll();
break;
}
//这里已经得到最终的 F_SN 和 F_IC
//下面连接数据库,核对输入的F_IC,得到对应的ItemName, F_IN
string Connstr = "Provider = Microsoft.Jet.OLEDB.4.0; Jet OLEDB:Database Password=rctool;Data Source = convert.mdb";
OleDbConnection Conn = new OleDbConnection(Connstr);
Conn.Open();
string CMDStr = "SELECT * FROM cvn WHERE code='" + F_IC + "'";
OleDbCommand CMD = new OleDbCommand(CMDStr, Conn);
OleDbDataReader dr = CMD.ExecuteReader();
if (dr.HasRows == false)
{
MessageBox.Show("This code doesn't exist in database");
Conn.Close();
textBoxCode.Focus();
textBoxCode.SelectAll();
return;
}
if (dr.HasRows == true)
{
dr.Read();
F_IN = dr["name"].ToString();
Conn.Close();
}
//这里已经得到最终的 F_IN
//至此F_SN,F_IC,F_IN已经全部得到
//下面开始输出这些参数,生成新的打印脚本script-go.txt,脚本默认产生在程序目录下面
ScriptGen();
//下面将此脚本送到打印口
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Arguments = "/c copy script-go.txt LPT1 ";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.Start();
while (true)
{
if (cmd.HasExited)
{
break;
}
System.Threading.Thread.Sleep(400);
}
textBoxCode.Clear();
textBoxSN.Focus();
textBoxSN.SelectAll();
}
}
}
9.在发送给Zebra打印机之前,使用.NET WinForm打印预览ZPL II命令
我有一个.NET Windows应用程序,使用ZPL II或EPL2向Zebra打印机打印命令.在直接从Zebra打印机打印之前,是否有任何方式打印预览表格中的数据?
看看 Labelary web service,它允许您以编程方式将ZPL转换为图像.
只需构建一个包含您要呈现的ZPL的URL,从Web服务器获取图像,并从应用程序中向用户显示图像.
string zpl = "YOUR ZPL HERE";
string url = "http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/" + zpl;
using (WebClient client = new WebClient()) {
client.DownloadFile(url, "zpl.png");
}
10.把图像转换成斑马打印机的命令
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace EHX.QrCode
{
///
/// 斑马工具类,把图像转换成斑马打印机的命令
///
public class ZebraUnity
{
#region 定义私有字段
///
/// 线程锁,防止多线程调用。
///
private static object SyncRoot = new object();
///
/// ZPL压缩字典
///
private static List compressDictionary = new List();
#endregion
#region 构造方法
static ZebraUnity()
{
InitCompressCode();
}
#endregion
#region 定义属性
///
/// 图像的二进制数据
///
public static byte[] GraphBuffer { get; set; }
///
/// 图像的宽度
///
private static int GraphWidth { get; set; }
///
/// 图像的高度
///
private static int GraphHeight { get; set; }
private static int RowSize
{
get
{
return (((GraphWidth) + 31) >> 5) 0)
{
return GraphWidth / 8 + 1;
}
else
{
return GraphWidth / 8;
}
}
}
#endregion
#region 位图转斑马指令字符串
///
/// 位图转斑马指令字符串
///
/// 位图数据
/// 总共的字节数
/// 每行的字节数
/// 斑马ZPL 2命令
public static string BmpToZpl(byte[] bitmap, out int totalBytes, out int rowBytes)
{
try
{
GraphBuffer = bitmap;
byte[] bmpData = getBitmapData();
string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
string textBitmap = CompressLZ77(textHex);
totalBytes = GraphHeight * RowRealBytesCount;
rowBytes = RowRealBytesCount;
return textBitmap;
}
catch (Exception ex)
{
throw ex;
}
}
///
/// 位图转ZPL指令
///
/// 位图
/// 返回参数总共字节数
/// 返回参数每行的字节数
/// ZPL命令
public static string BmpToZpl(Image bitmap, out int totalBytes, out int rowBytes)
{
using (MemoryStream stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Bmp);
return BmpToZpl(stream.ToArray(), out totalBytes, out rowBytes);
}
}
///
/// 根据图片生成图片的ASCII 十六进制
///
/// 原始图片
/// 总共字节数
/// 每行的字节数
/// ASCII 十六进制
public static string BitmapToHex(Image sourceBmp, out int totalBytes, out int rowBytes)
{
// 转成单色图
Bitmap grayBmp = ConvertToGrayscale(sourceBmp as Bitmap);
// 锁定位图数据
Rectangle rect = new Rectangle(0, 0, grayBmp.Width, grayBmp.Height);
System.Drawing.Imaging.BitmapData bmpData = grayBmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, grayBmp.PixelFormat);
// 获取位图数据第一行的起始地址
IntPtr ptr = bmpData.Scan0;
// 定义数组以存放位图的字节流数据
// 处理像素宽对应的字节数,如不为8的倍数,则对最后一个字节补0
int width = (int)Math.Ceiling(grayBmp.Width / 8.0);
// 获取位图实际的字节宽,这个值因为要考虑4的倍数关系,可能大于width
int stride = Math.Abs(bmpData.Stride);
// 计算位图数据实际所占的字节数,并定义数组
int bitmapDataLength = stride * grayBmp.Height;
byte[] ImgData = new byte[bitmapDataLength];
// 从位图文件复制图像数据到数组,从实际图像数据的第一行开始;因ptr指针而无需再考虑行倒序存储的处理
System.Runtime.InteropServices.Marshal.Copy(ptr, ImgData, 0, bitmapDataLength);
// 计算异或操作数,以处理包含图像数据但又有补0操作的那个字节
byte mask = 0xFF;
// 计算这个字节补0的个数
//int offset = 8 * width - grayBmp.Width;
int offset = 8 - (grayBmp.Width % 8);
//offset %= 8;
offset = offset % 8;
// 按补0个数对0xFF做相应位数的左移位操作
mask threshold)
{
destinationValue += (byte)pixelValue;
}
if (pixelValue == 1)
{
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = 0;
pixelValue = 128;
}
else
{
pixelValue >>= 1;
}
sourceIndex += 4;
}
if (pixelValue != 128)
{
destinationBuffer[destinationIndex] = destinationValue;
}
}
// Copy binary image data to destination bitmap
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);
// Unlock destination bitmap
destination.UnlockBits(destinationData);
// Dispose of source if not originally supplied bitmap
if (source != pimage)
{
source.Dispose();
}
// Return
return destination;
}
///
/// 获取单色位图数据(1bpp),不含文件头、信息头、调色板三类数据。
///
///
private static byte[] getBitmapData()
{
MemoryStream srcStream = new MemoryStream();
MemoryStream dstStream = new MemoryStream();
Bitmap srcBmp = null;
Bitmap dstBmp = null;
byte[] srcBuffer = null;
byte[] dstBuffer = null;
byte[] result = null;
try
{
srcStream = new MemoryStream(GraphBuffer);
srcBmp = Bitmap.FromStream(srcStream) as Bitmap;
srcBuffer = srcStream.ToArray();
GraphWidth = srcBmp.Width;
GraphHeight = srcBmp.Height;
//dstBmp = srcBmp.Clone(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), PixelFormat.Format1bppIndexed);
dstBmp = ConvertToGrayscale(srcBmp);
dstBmp.Save(dstStream, ImageFormat.Bmp);
dstBuffer = dstStream.ToArray();
result = dstBuffer;
int bfOffBits = BitConverter.ToInt32(dstBuffer, 10);
result = new byte[GraphHeight * RowRealBytesCount];
////读取时需要反向读取每行字节实现上下翻转的效果,打印机打印顺序需要这样读取。
for (int i = 0; i < GraphHeight; i++)
{
int sindex = bfOffBits + (GraphHeight - 1 - i) * RowSize;
int dindex = i * RowRealBytesCount;
Array.Copy(dstBuffer, sindex, result, dindex, RowRealBytesCount);
}
for (int i = 0; i < result.Length; i++)
{
result[i] ^= 0xFF;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
finally
{
if (srcStream != null)
{
srcStream.Dispose();
srcStream = null;
}
if (dstStream != null)
{
dstStream.Dispose();
dstStream = null;
}
if (srcBmp != null)
{
srcBmp.Dispose();
srcBmp = null;
}
if (dstBmp != null)
{
dstBmp.Dispose();
dstBmp = null;
}
}
return result;
}
#endregion
#region LZ77图像字节流压缩方法
private static string CompressLZ77(string text)
{
//将转成16进制的文本进行压缩
string result = string.Empty;
char[] arrChar = text.ToCharArray();
int count = 1;
for (int i = 1; i < text.Length; i++)
{
if (arrChar[i - 1] == arrChar[i])
{
count++;
}
else
{
result += convertNumber(count) + arrChar[i - 1];
count = 1;
}
if (i == text.Length - 1)
{
result += convertNumber(count) + arrChar[i];
}
}
return result;
}
private static string DecompressLZ77(string text)
{
string result = string.Empty;
char[] arrChar = text.ToCharArray();
int count = 0;
for (int i = 0; i < arrChar.Length; i++)
{
if (isHexChar(arrChar[i]))
{
//十六进制值
result += new string(arrChar[i], count == 0 ? 1 : count);
count = 0;
}
else
{
//压缩码
int value = GetCompressValue(arrChar[i]);
count += value;
}
}
return result;
}
private static int GetCompressValue(char c)
{
int result = 0;
for (int i = 0; i < compressDictionary.Count; i++)
{
if (c == compressDictionary[i].Key)
{
result = compressDictionary[i].Value;
}
}
return result;
}
private static bool isHexChar(char c)
{
return c > 47 && c < 58 || c > 64 && c < 71 || c > 96 && c < 103;
}
private static string convertNumber(int count)
{
//将连续的数字转换成LZ77压缩代码,如000可用I0表示。
string result = string.Empty;
if (count > 1)
{
while (count > 0)
{
for (int i = compressDictionary.Count - 1; i >= 0; i--)
{
if (count >= compressDictionary[i].Value)
{
result += compressDictionary[i].Key;
count -= compressDictionary[i].Value;
break;
}
}
}
}
return result;
}
private static void InitCompressCode()
{
//G H I J K L M N O P Q R S T U V W X Y 对应1,2,3,4……18,19。
//g h i j k l m n o p q r s t u v w x y z 对应20,40,60,80……340,360,380,400。
for (int i = 0; i < 19; i++)
{
compressDictionary.Add(new KeyValuePair (Convert.ToChar(71 + i), i + 1 ));
}
for (int i = 0; i < 20; i++)
{
compressDictionary.Add(new KeyValuePair(Convert.ToChar(103 + i), (i + 1) * 20));
}
}
#endregion
}
}
View Code
11.网络打印 C#代码
// Printer IP Address and communication port
string ipAddress = "10.3.14.42";
int port = 9100;
// ZPL Command(s)
string ZPLString =
"^XA" +
"^FO50,50" +
"^A0N50,50" +
"^FDHello, World!^FS" +
"^XZ";
try
{
// Open connection
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
client.Connect(ipAddress, port);
// Write ZPL String to connection
System.IO.StreamWriter writer =
new System.IO.StreamWriter(client.GetStream());
writer.Write(ZPLString);
writer.Flush();
// Close Connection
writer.Close();
client.Close();
}
catch (Exception ex)
{
// Catch Exception
}
|